import { ElLoading } from 'element-plus'
import { LoadingInstance } from 'element-plus/es/components/loading/src/loading'
import { LoadingOptions } from 'element-plus/es/components/loading/src/types'

let loadingInstance: LoadingInstance | null = null

export const ElLoadingGlobalOpen_Name = 'ElLoadingGlobalOpen'
export const ElLoadingGlobalClose_Name = 'ElLoadingGlobalClose'
export const ElLoadingGlobal_Name = 'ElLoadingGlobal'
export const ElLoadingGlobalOpenType_Name = 'ElLoadingGlobalOpenType'
export const ElLoadingGlobalCloseType_Name = 'ElLoadingGlobalCloseType'
export const ElLoadingGlobalType_Name = 'ElLoadingGlobalType'

/**
 * 开启全局 loading
 *
 * @param {LoadingOptions} options loading 配置项
 */
export const ElLoadingGlobalOpen = (options: LoadingOptions = {}) => {
  loadingInstance = ElLoading.service({
    body: true,
    fullscreen: true,
    lock: true,
    text: '加载中...',
    background: 'rgba(0, 0, 0, 0.7)',
    ...options
  })
}

export type ElLoadingGlobalOpenType = typeof ElLoadingGlobalOpen

/**
 * 关闭全局 loading
 */
export const ElLoadingGlobalClose = () => {
  if (loadingInstance) {
    loadingInstance.close()
    loadingInstance = null
  }
}

export type ElLoadingGlobalCloseType = typeof ElLoadingGlobalClose

/**
 * 全局 loading
 *
 * @param 配置选项：
 * - isLoading 在延时器时间到达后，是否开启全局 loading
 * - handler 处理函数
 * - timeout 延时器时间，单位：毫秒，默认：100
 * - errHandler 错误处理函数
 * - options loading 配置项
 */
export const ElLoadingGlobal = async ({
  isLoading,
  handler,
  timeout = 100,
  errHandler = () => {},
  options = {}
}: {
  isLoading: () => boolean
  handler: () => Promise<void>
  timeout?: number
  errHandler?: (e: any) => void
  options?: LoadingOptions
}) => {
  setTimeout(() => {
    if (isLoading()) ElLoadingGlobalOpen(options)
  }, timeout)
  try {
    await handler()
  } catch (e) {
    errHandler(e)
  } finally {
    ElLoadingGlobalClose()
  }
}

export type ElLoadingGlobalType = typeof ElLoadingGlobal
